package com.sky.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sky.context.BaseContext;
import com.sky.dto.BatchUpdateRequest;
import com.sky.dto.NoteDTO;
import com.sky.dto.PageQuery;
import com.sky.entity.*;
import com.sky.mapper.UserMapper;
import com.sky.repository.BookRepository;
import com.sky.repository.NoteRepository;
import com.sky.repository.ReviewRepository;
import com.sky.repository.UserActionLogRepository;
import com.sky.result.PageResult;
import com.sky.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class NoteServiceImpl {
    private static final Logger logger = LoggerFactory.getLogger(NoteServiceImpl.class);
    private final NoteRepository noteRepository;
    private final UserMapper userMapper;
    private final BookRepository bookRepository;
    private final ReviewRepository reviewRepository;
    private final UserActionLogRepository logRepository;

    @Autowired
    public NoteServiceImpl(NoteRepository noteRepository,
                           UserMapper userMapper,
                           BookRepository bookRepository, ReviewRepository reviewRepository,UserActionLogRepository logRepository) {
        this.noteRepository = noteRepository;
        this.userMapper = userMapper;
        this.bookRepository = bookRepository;
        this.reviewRepository = reviewRepository;
        this.logRepository = logRepository;
    }

    //添加笔记
    public void add(NoteDTO noteDTO) {
        Note note = new Note();
        note.setUId(BaseContext.getCurrentId());
        note.setStatus(Note.PENDING_REVIEW);
        note.setUpdateTime(noteDTO.getCreateTime());
        BeanUtils.copyProperties(noteDTO, note);
        noteRepository.save(note);
        // 记录操作日志
        UserActionLog log = new UserActionLog();
        log.setAction("note");
        log.setBId(note.getBId());
        log.setTimestamp(new Date());
        // 假设通过安全上下文获取当前用户
        log.setUId(BaseContext.getCurrentId());
        logRepository.save(log);
        logger.info("Note was added: {}", noteDTO);
    }

    //根据笔记id获取详情结果
    public NoteResult getNoteResult(String id) {
        Note note = noteRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("Note not found with id: " + id));

        NoteVO noteVO = convertToNoteVO(note);
        UserInfoVO userInfo = getUserInfo();

        return NoteResult.builder()
                .note(noteVO)
                .userInfo(userInfo)
                .build();
    }

    //分页查询已发布的笔记
    public PageResult list(PageQuery pageQuery) {
        Page<Note> page;
        if(pageQuery.getStatus()==null){
            page=noteRepository.findAll(
                    PageRequest.of(pageQuery.getPage()-1,pageQuery.getSize(),Sort.by(Sort.Direction.DESC,"createTime"))
            );
        }
        else {
            page=noteRepository.findByStatus(
                    pageQuery.getStatus(),
                    PageRequest.of(pageQuery.getPage()-1,pageQuery.getSize(),Sort.by(Sort.Direction.DESC,"createTime"))
            );
        }
        List<NoteVO> record = page.getContent().stream().map(this::convertToNoteVO)
                .collect(Collectors.toList());
        return new PageResult(page.getTotalElements(),record);
    }

    private UserInfoVO getUserInfo() {
        Integer uId = BaseContext.getCurrentId();
        User user = userMapper.getById(uId);

        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(user, userInfoVO);
        return userInfoVO;
    }

    private NoteVO convertToNoteVO(Note note) {
        if (note == null) return null;

        NoteVO noteVO = new NoteVO();
        BeanUtils.copyProperties(note, noteVO);

        // 设置统计信息（实际项目中应从数据库获取）
        noteVO.setLikeCount(24);
        noteVO.setCommentCount(25);
        noteVO.setShareCount(72);
        noteVO.setCollectCount(15);

        // 设置作者信息
        User author = userMapper.getById(note.getUId());
        noteVO.setAuthor(convertToAuthorVO(author));

        // 设置书籍信息
        Book book = bookRepository.findById(note.getBId()).orElse(null);
        noteVO.setBook(convertToBookVO(book));

        return noteVO;
    }

    private AuthorVO convertToAuthorVO(User user) {
        if (user == null) return null;

        AuthorVO authorVO = new AuthorVO();
        BeanUtils.copyProperties(user, authorVO);
        return authorVO;
    }

    private BookVO convertToBookVO(Book book) {
        if (book == null) return null;

        BookVO bookVO = new BookVO();
        BeanUtils.copyProperties(book, bookVO);
        return bookVO;
    }

    /**
     * 修改笔记状态
     * @param id
     * @param status
     */
    public void update(String id, Integer status) {
        Note note = noteRepository.findById(id).orElse(null);
        note.setStatus(status);
        note.setUpdateTime(new Date());
        noteRepository.save(note);
    }
    /**
     * 批量修改笔记状态
     * @param request
     */
    @Transactional
    public void batchUpdateStatus(BatchUpdateRequest request) {
        int batchSize = 100; // 每批处理100条
        List<String> ids = request.getIds();
        Integer status = request.getStatus();
        for (int i = 0; i < ids.size(); i += batchSize) {
            List<String> batchIds = ids.subList(i, Math.min(i + batchSize, ids.size()));
            // 1. 查询出这批记录
            List<Note> notes = (List<Note>) noteRepository.findAllById(batchIds);

            // 2. 批量更新状态和更新时间
            notes.forEach(note -> {
                note.setStatus(request.getStatus());
                note.setUpdateTime(new Date());  // 设置更新时间
            });

            // 3. 批量保存
            noteRepository.saveAll(notes);
        }
    }

}